package com.hx.shiro.realm;

import com.hx.shiro.dao.UserDao;
import com.hx.shiro.vo.User;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author: hanxin
 * @Date: 2020/9/13 23:44
 * @Version 1.0
 */
public class CustomRealm extends AuthorizingRealm {

  @Autowired
  private UserDao userDao;

  // 授权
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

    String userName = (String) principalCollection.getPrimaryPrincipal();
    Set<String> roles = getRolesByUserName(userName);
    Set<String> permissions = getPermissionsByRole(roles);

    SimpleAuthorizationInfo simpleAuthorizationInfo = new
        SimpleAuthorizationInfo();
    // 设置角色
    simpleAuthorizationInfo.setRoles(roles);
    // 设置权限
    simpleAuthorizationInfo.setStringPermissions(permissions);
    return simpleAuthorizationInfo;
  }

  // 认证
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
      throws AuthenticationException {

    // 1.从主体传过来的认证信息中获取用户信息
    String userName = (String) authenticationToken.getPrincipal();
    // 2.通过用户名到数据库中获取凭证
    String password = getPasswordByUserName(userName);

    SimpleAuthenticationInfo authenticationInfo = new
        SimpleAuthenticationInfo(userName, password, "customrealm");
    // 加盐
    authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("hw"));
    return authenticationInfo;
  }

  /**
   * 数据库 读取密码
   *
   * @param userName yonghu
   * @return mima
   */
  private String getPasswordByUserName (String userName) {
    // 读数据库 md5 加密 加盐
    User user = userDao.getUserByUsername(userName);
    if(user != null){
      return user.getPassword();
    }
    return null;
  }

  /**
   * 数据库 读取角色
   *
   * @return set
   */
  private Set<String> getRolesByUserName(String userName) {
    List<String> list = userDao.getRolesByUserName(userName);
    Set<String> set = new HashSet<String>(list);
    return set;
  }

  /**
   * 数据库 读取权限
   *
   * @return set
   */
  private Set<String> getPermissionsByRole(Set<String> roles) {
    System.out.println("从数据库中获取权限数据");
    Set<String> set = new HashSet<String>();
    set.add("user:delete");
    return set;
  }

}
